package pure.engine.world 
{
	import flash.geom.*;
	import pure.engine.core.ns_despair;
	import pure.engine.model.Model2D;
	use namespace ns_despair;
	
	/**
	 * 区块融合
	 * [Author] - PURE
	 * 
	 */
public class RegionFusion 
{
	public function RegionFusion(regionSize:int, numExtendedRegion:int) 
	{
		this.m_regionSize         =  regionSize;
		this.m_numExtendedRegion  =  numExtendedRegion;
		this.m_outOfBounds        =  Region.getRegion();
	}
	
	
	
	/**
	 * 重置区块列表
	 * 
	 * [Hint] - 开始时需要调用
	 */
	ns_despair function setRegions(RX:int, RY:int, regionData:Array):void
	{
		var i:int, j:int;
		var region:Region;
		
		m_numRegionX = RX;
		m_numRegionY = RY;
		
		for (i = 0; i < RY + m_numExtendedRegion * 2; i++)
		{
			m_regionList[i] = new Vector.<Region>();
			for (j = 0; j < RX +m_numExtendedRegion * 2; j++)
			{
				m_regionList[i][j] = region = Region.getRegion();
			}
		}
		
		if(regionData)
		{
			for (i = m_numExtendedRegion; i < RY + m_numExtendedRegion ; i++)
			{
				for (j = m_numExtendedRegion; j < RX + m_numExtendedRegion; j++)
				{
					m_regionList[i][j] = region = Region.getRegion();
					region.m_data = regionData[i][j];
				}
			}
		}
	}
	
	
	/**
	 * 清空区块列表
	 */
	ns_despair function clearRegions():void
	{
		var i:int, j:int;
		var numRows:int = m_numRegionY + m_numExtendedRegion * 2;
		var numCols:int = m_numRegionX + m_numExtendedRegion * 2;
		
		for (i = 0; i < numRows; i++)
		{
			for (j = 0; j < numCols; j++)
			{
				m_regionList[i][j].recycle();
			}
			m_regionList[i].length = 0;;
		}
		m_regionList.length = 0;
		m_outOfBounds.clear();
	}
	

	/**
	 * 加入模型
	 * 
	 * [Return] - 区块位置
	 */
	ns_despair function addModel(model:Model2D):int
	{
		var RX:int, RY:int;
		
		RX  =  int(model.m_x / m_regionSize < 0 ? model.m_x / m_regionSize - 1 : model.m_x / m_regionSize) + m_numExtendedRegion;
		RY  =  int(model.m_y / m_regionSize < 0 ? model.m_y / m_regionSize - 1 : model.m_y / m_regionSize) + m_numExtendedRegion;
		
		// 定位区块
		if (RX < 0 || RY < 0 || RX > m_numRegionX + m_numExtendedRegion|| RY > m_numRegionY + m_numExtendedRegion)
		{
			m_outOfBounds.add(model);
			return model.m_grid = -1;
		}
		m_regionList[RY][RX].add(model);
		
		return model.m_grid = (RY << 8) || RX;
	}

	
	/**
	 * 移动模型
	 * 
	 * [Return] - [-2]未变，[>= -1]区块位置
	 */
	ns_despair function moveModel(model:Model2D):int
	{
		var RX:int, RY:int, grid:int, oldGrid:int;
		
		RX  =  int(model.m_x / m_regionSize < 0 ? model.m_x / m_regionSize - 1 : model.m_x / m_regionSize) + m_numExtendedRegion;
		RY  =  int(model.m_y / m_regionSize < 0 ? model.m_y / m_regionSize - 1 : model.m_y / m_regionSize) + m_numExtendedRegion;
		
		// 重新定位区块
		grid = Boolean(RX < 0 ||RY < 0 || RX > m_numRegionX + m_numExtendedRegion ||RY > m_numRegionY + m_numExtendedRegion) ? -1 : (RY << 8) | RX;
		
		// 区块变化
		oldGrid = model.m_grid;
		if (oldGrid != grid)
		{
			// 从原区块移除
			if (oldGrid == -1)
			{
				m_outOfBounds.remove(model);
			}
			else
			{
				m_regionList[oldGrid >> 8][oldGrid & 0xFF].remove(model);
			}
			
			// 加入到新区块
			if (grid == -1)
			{
				m_outOfBounds.add(model);
			}
			else
			{
				m_regionList[grid >> 8][grid & 0xFF].add(model);
			}
			return model.m_grid = grid;
		}
		return -2;
	}
	
	
	/**
	 * 移除模型
	 */
	ns_despair function removeModel(model:Model2D):void
	{
		var grid:int = model.m_grid;
		
		if (grid == -1)
		{
			m_outOfBounds.remove(model);
		}
		else
		{
			m_regionList[grid >> 8][grid & 0xFF].remove(model);
		}
	}
	
	
	/**
	 * 移除全部模型
	 */
	ns_despair function removeAllModels():void
	{
		var i:int, j:int;
		var numRows:int = m_numRegionX + m_numExtendedRegion * 2;
		var numCols:int = m_numRegionX + m_numExtendedRegion * 2;
		
		for (i = 0; i < numRows; i++)
		{
			for (j = 0; j < numCols; j++)
			{
				m_regionList[i][j].clear();
			}
			m_regionList[i].length = 0;;
		}
		m_regionList.length = 0;
		m_outOfBounds.clear();
	}
	
	
	/**
	 * 获取某世界坐标点附近全部模型
	 */
	ns_despair function getAllModelByPoint(wx:Number, wy:Number):Array
	{
		var i:int, j:int, RX:int, RY:int;
		
		//RX  =  int(wx / m_regionSize < 0 ? wx / m_regionSize - 1 : wx / m_regionSize) + m_numExtendedRegion;
		//RY  =  int(wy / m_regionSize < 0 ? wy / m_regionSize - 1 : wy / m_regionSize) + m_numExtendedRegion;
		
		RX  =  int(wx / m_regionSize) + m_numExtendedRegion;
		RY  =  int(wy / m_regionSize) + m_numExtendedRegion;
		
		for (i = RY - m_numExtendedRegion; i <= RY + m_numExtendedRegion; i++)
		{
			for (j = RX - m_numExtendedRegion; j <= RX + m_numExtendedRegion; j++)
			{
				cachedArray.push.apply(null, m_regionList[i][j].m_modelList);
			}
		}
		return cachedArray;
	}
	
	
	
	
	
	//======================
	// Member
	//======================
	
	
	ns_despair var cachedArray:Array = [];  // 缓存数组
	
	
	ns_despair var m_regionList:Vector.<Vector.<Region>> = new Vector.<Vector.<Region>>();  // 区块二维数组
	
	ns_despair var m_outOfBounds:Region;  // 边界外区块
	
	ns_despair var m_numRegionX:int, m_numRegionY:int;  // 总区块数量
	
	ns_despair var m_numExtendedRegion:int;  // 延伸区块数量
	
	ns_despair var m_regionSize:int;  // 区块大小

}

}